package com.helasasa.maxfunds.lineofcredit.cashloan.cameroon.screen.risking.subview

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
import android.graphics.drawable.BitmapDrawable
import android.util.AttributeSet
import android.view.View
import com.helasasa.maxfunds.lineofcredit.cashloan.R
import java.util.Timer
import java.util.TimerTask

interface IRiskingCameroonProcessBarListener {
    /** 间隔回调 */
    fun onTick(tick: Int)

    /** 周期完成回调 */
    fun onCompleted()
}

@SuppressLint("UseCompatLoadingForDrawables")
class RiskingCameroonProcessBar(context: Context, attrs: AttributeSet? = null) :
    View(context, attrs) {

    /** 回调 */
    private var listener: IRiskingCameroonProcessBarListener? = null

    /** 区间 0-1 */
    private var process: Float = 0.0F

    /** 环宽度 */
    private val circleWidth = 14F.dpToPx()

    /** 刻度长度 */
    private val scaleWidth = circleWidth * 1.5F + 4F.dpToPx()

    /** 计时器 */
    private var timer = Timer()

    /** 圆点图片 */
    private var mPointBitmap: Bitmap? = null

    /** 矩阵,用于对图片进行一些操作 */
    private var mMatrix: Matrix = Matrix()

    /** 当前点的实际位置 */
    private var pos: FloatArray = FloatArray(2)

    /** 当前点的tangent值,用于计算图片所需旋转的角度 */
    private var tan: FloatArray = FloatArray(2)

    /** 是否结束 */
    private var isEnd = false

    private val bgCirclePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#EAE9F3")
        strokeWidth = circleWidth
        style = Paint.Style.STROKE
        isAntiAlias = true
        strokeCap = Paint.Cap.ROUND
        strokeJoin = Paint.Join.ROUND
    }

    private val processCirclePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#5277D6")
        strokeWidth = circleWidth
        isAntiAlias = true
        style = Paint.Style.STROKE
        strokeCap = Paint.Cap.ROUND
        strokeJoin = Paint.Join.ROUND
    }

    private val pointPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#FFFFFF")
        strokeWidth = circleWidth
        isAntiAlias = true
        style = Paint.Style.FILL
        strokeCap = Paint.Cap.ROUND
        strokeJoin = Paint.Join.ROUND
    }

    private val linePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#000000")
        strokeWidth = 2F
        style = Paint.Style.STROKE
        isAntiAlias = true
        strokeCap = Paint.Cap.ROUND
        strokeJoin = Paint.Join.ROUND
    }

    init {
        mPointBitmap =
            (context.getDrawable(R.drawable.pic_risking_point) as BitmapDrawable).bitmap
    }

    @SuppressLint("DrawAllocation", "UseCompatLoadingForDrawables")
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 画刻度
        // top
        val topStartX = width / 2F
        val topStartY = circleWidth
        val topEndX = width / 2F
        val topEndY = scaleWidth
        canvas.drawLine(
            topStartX,
            topStartY,
            topEndX,
            topEndY,
            linePaint
        )

        // right
        val rightStartX = width - circleWidth
        val rightStartY = width / 2F
        val rightEndX = width - scaleWidth
        val rightEndY = width / 2F
        canvas.drawLine(
            rightStartX,
            rightStartY,
            rightEndX,
            rightEndY,
            linePaint
        )

        // bottom
        val bottomStartX = width / 2F
        val bottomStartY = width - circleWidth
        val bottomEndX = width / 2F
        val bottomEndY = width - scaleWidth
        canvas.drawLine(
            bottomStartX,
            bottomStartY,
            bottomEndX,
            bottomEndY,
            linePaint
        )

        // left
        val leftStartX = circleWidth
        val leftStartY = width / 2F
        val leftEndX = scaleWidth
        val leftEndY = width / 2F
        canvas.drawLine(
            leftStartX,
            leftStartY,
            leftEndX,
            leftEndY,
            linePaint
        )

        // 画背景环
        val widthF = width.toFloat() - circleWidth
        canvas.drawArc(
            circleWidth,
            circleWidth,
            widthF,
            widthF,
            0F,
            360F,
            false,
            bgCirclePaint
        )

        // 画进度圆环
        val sweepAngle = 360 * this.process
        canvas.drawArc(
            circleWidth,
            circleWidth,
            widthF,
            widthF,
            -90F,
            sweepAngle,
            false,
            processCirclePaint
        )

        // 画圆点
        if (mPointBitmap != null) {
            val path = Path()
            path.addArc(circleWidth, circleWidth, widthF, widthF, -90F, sweepAngle)
            val measure = PathMeasure(path, false)
            measure.getPosTan(measure.length, pos, tan)
            // 画圆点
            //canvas.drawCircle(pos[0], pos[1], circleWidth / 2, pointPaint)

            val bitmapWidthRadius = mPointBitmap?.width!! / 2F
            val bitmapHeightRadius = mPointBitmap?.height!! / 2F
            mMatrix.reset()
            mMatrix.postScale(1F, 1F)
            mMatrix.postRotate(sweepAngle, bitmapWidthRadius, bitmapHeightRadius)
            mMatrix.postTranslate(
                pos[0] - bitmapWidthRadius,
                pos[1] - bitmapHeightRadius
            )
            // 画图标
            canvas.drawBitmap(mPointBitmap!!, mMatrix, pointPaint)
        }
    }

    fun updateProcess(curValue: Float) {
        this.process = if (curValue > 1) {
            1F
        } else if (curValue < 0) {
            0F
        } else {
            curValue
        }
        invalidate()
    }

    fun start() {
        // 15秒
        val maxSec = 15000
        // 动画间隔
        val aniEdg = 50F
        // 执行增量
        val internalEdg = 1F / maxSec * aniEdg
        // 当前秒数
        var curTick = 0

        timer.cancel()
        timer = Timer()
        timer.schedule(object : TimerTask() {
            override fun run() {
                if (curTick == 0) {
                    val sec = 1
                    listener?.onTick(sec)
                } else {
                    val mod = curTick % 20
                    if (mod == 0) {
                        val sec = (curTick / 20) + 1
                        listener?.onTick(sec)
                    }
                }
                curTick += 1

                val nextProcess = process + internalEdg
                updateProcess(nextProcess)
                if (nextProcess > 1) {
                    if (isEnd) {
                        timer.cancel()
                        listener?.onCompleted()
                        return
                    } else {
                        process = 0F
                        curTick = 0
                    }
                }
            }
        }, 500L, aniEdg.toLong())
    }

    fun stop() {
        timer.cancel()
        removeListener()
    }

    private fun removeListener() {
        this.listener = null
    }

    fun addListener(listener: IRiskingCameroonProcessBarListener? = null) {
        this.listener = listener
    }

    // 将 dp 转换为像素
    private fun Float.dpToPx(): Float {
        return this * context.resources.displayMetrics.density
    }
}